package com.jin.webvideo.base.util;

import java.util.*;

/**
 * @ClassName Collections
 * @description:
 * @author: biao532
 * @create: 2023-11-23 23:03
 * @Version 1.0
 **/
public class CollectionsUtil {
    public interface MapConverter<L, K, V>{
        K convertKey(L accept);
        V convertVal(L accept);
    }

    @FunctionalInterface
    public interface Filter<T> {
        boolean filter(T t);
    }
    @FunctionalInterface
    public interface SimpleVisitor<T> {
        void visit(T t);
    }

    @FunctionalInterface
    public interface Visitor<T> {
        void visit(int idx, T t);
    }
    @FunctionalInterface
    public interface Converter<T, V> {
        V convert(int i, T t);
    }

    /**
     * 判断Collection是否为null或空
     * @param collection
     * @return
     */
    public static boolean isEmpty(Collection collection) {
        return collection == null || collection.isEmpty();
    }

    /**
     * 如果list为空，则返回defaultList
     * @param list
     * @param defaultList
     * @param <T>
     * @return
     */
    public static<T> List<T> getOrDefault(List<T> list, List<T> defaultList){
        return isEmpty(list)?defaultList:list;
    }

    /**
     * 如果list为空或不存在index的数据，则返回defaultList
     * @param list
     * @param index
     * @param defaultValue
     * @param <T>
     * @return
     */
    public static<T> T getOrDefault(List<T> list, int index, T defaultValue){
        return (isEmpty(list) || list.size() <= index)?defaultValue:list.get(index);
    }

    /**
     * 将T列表转化为V列表
     * @param collection
     * @param converter
     * @param <T>
     * @param <V>
     * @return
     */
    public static <T, V> List<V> convert(Collection<T> collection, ObjectsUtil.Converter<T, V> converter) {
        List<V> l = new ArrayList<>(collection.size());
        CollectionsUtil.foreach(collection, (c) -> {
            l.add(ObjectsUtil.convert(c, converter));
        });
        return l;
    }

    /**
     * 将T列表转化为V列表
     * @param list
     * @param converter
     * @param <T>
     * @param <V>
     * @return
     */
    public static <T, V> List<V> convert(List<T> list, Converter<T, V> converter) {
        List<V> l = new ArrayList<>(list.size());
        CollectionsUtil.foreach(list, (i, c) -> {
            l.add(converter.convert(i, c));
        });
        return l;
    }

    /**
     * 获取collection中第一个符合条件的项，不存在则返回null
     * @param collection
     * @param filter
     * @param <T>
     * @return
     */
    public static<T> T first(Collection<T> collection, Filter<T> filter) {
        if (collection == null) {
            return null;
        }
        for (T c :collection) {
            if (filter.filter(c)) {
                return c;
            }
        }
        return null;
    }

    /**
     * 获取collection中符合条件的项
     * @param collection
     * @param filter
     * @param <E>
     * @return
     */
    public static<E> List<E> filter (List<E> collection, Filter<E> filter) {
        if (collection == null) {
            return null;
        }
        List<E> list = new ArrayList<>(collection.size());
        CollectionsUtil.foreach(collection, (c)-> {
            if (filter.filter(c)) {
                list.add(c);
            }
        });
        return list;
    }

    /**
     * 移除collection中符合条件的项
     * @param collection
     * @param filter
     * @param <E>
     */
    public static<E> void removeAll (Collection<E> collection, Filter<E> filter) {
        if (collection == null) {
            return ;
        }
        Iterator<E> iterator = collection.iterator();
        while (iterator.hasNext()) {
            E c = iterator.next();
            if (filter.filter(c)) {
                iterator.remove();
            }
        }
    }

    /**
     * 对Collection中每一项进行操作
     * @param collection
     * @param simpleVisitor
     * @param <T>
     */
    public static<T> void foreach(Collection<T> collection, SimpleVisitor<T> simpleVisitor) {
        CollectionsUtil.foreach(collection, (c)-> {
            simpleVisitor.visit(c);
            return true;
        });
    }

    /**
     * 对Collection中每一项进行操作
     * @param collection
     * @param visitor
     * @param <T>
     */
    public static<T> void foreach(Collection<T> collection, Visitor<T> visitor) {
        if (collection == null) {
            return;
        }
        int i = 0;
        for (T c :collection) {
            visitor.visit(i++, c);
        }
    }

    /**
     * 将collection转化为以key value 为键值对的 map
     * @param collection
     * @param key
     * @param value
     * @param <T>
     * @param <V>
     * @return
     */
    public static <T, V> Map<V, V> convert(Collection<Map<T,V>> collection, T key, T value){
        return convert(collection, new MapConverter<Map<T, V>, V, V>() {
            @Override
            public V convertKey(Map<T, V> accept) {
                return accept.get(key);
            }

            @Override
            public V convertVal(Map<T, V> accept) {
                return accept.get(value);
            }
        });
    }

    /**
     * 将collection转化为map
     * @param collection
     * @param converter
     * @param <T>
     * @param <K>
     * @param <V>
     * @return
     */
    public static <T, K, V> Map<K, V> convert(Collection<T> collection, MapConverter<T, K, V> converter){
        Map<K, V> map = new HashMap<>(collection.size());
        if (isEmpty(collection)){
            return map;
        }
        for (T temp : collection){
            map.put(converter.convertKey(temp),converter.convertVal(temp));
        }
        return map;
    }

    /**
     * 去除collection中的重复项
     * @param collection
     * @param keyConverter
     * @param <T>
     * @param <V>
     */
    public static <T, V> void distinct(Collection<T> collection, ObjectsUtil.Converter<T, V> keyConverter) {
        Set<V> keySet = new HashSet<>();
        Iterator<T> iterator = collection.iterator();
        while (iterator.hasNext()) {
            T item = iterator.next();
            V v = keyConverter.convert(item);
            if (keySet.contains(v)) {
                iterator.remove();
                continue;
            }
            keySet.add(v);
        }
    }

    /**
     * 从list中随机选择一个数据
     * @param list
     * @param <T>
     * @return
     */
    public static<T> T random(List<T> list) {
        if (list == null) return null;
        int idx = (int) (Math.random()*100*list.size() / 100);
        return list.get(idx);
    }

    /**
     * 将可变参数转化成可add和remove 的 List
     * Arrays.asList 不支持 add和remove
     * @param t
     * @param <T>
     * @return
     */
    public static<T> List<T> asList(T... t) {
        return new ArrayList<>(Arrays.asList(t));
    }
    private static<T> void foreach(Collection<T> collection, Filter<T> filter) {
        if (collection == null) {
            return;
        }
        for (T c :collection) {
            if (!filter.filter(c)) {
                return;
            }
        }
    }
}
